﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using TagLib;
using System.Threading;
using System.Diagnostics;
using System.Drawing.Drawing2D;

namespace Kinect_MediaPlayer
{
    public partial class Form1 : Form
    {
        public static string rootDirectory = @"..\..";
        public static List<string> acceptedFileTypes = new List<string> { ".mp3", ".wav", ".wma", ".m4a" };

        private WMP MediaPlayer;
        private IniFile iniFile = new IniFile(rootDirectory + @"\Configuration\settings.ini");
        private string currentFolder = String.Empty;
        private string currentFile = String.Empty;
        private Song currentSong;
        private List<Song> SongsInFolder = new List<Song>();
        private List<Label> SongLabels = new List<Label>();

        private MainMenu mainMenu;
        private MenuItem fileMenuItem;
        private MenuItem closeMenuItem;
        private OpenFileDialog openFileDialog;
        private FolderBrowserDialog browseFolderDialog;

        private bool newSongSelected = false;
        private bool songPositionIsScrolling = false;
        private int volume = 200;

        // Library variables
        private Library Library;
        private int artistsPerRow = 4;
        private int artistRows = 1;
        private int libraryPage = 0;

        public Form1()
        {
            InitializeComponent();
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // reduces image flicker
            initializeBrowse();
            MediaPlayer = new WMP(this);

            Library = new Library(this, iniFile.IniReadValue("Library", "libraryPath"));
            Library.BuildLibrary();
            DrawAlbums();

            volumeSlider.Value = volume;
        }

        private void initializeBrowse()
        {
            this.mainMenu = new System.Windows.Forms.MainMenu();
            this.fileMenuItem = new System.Windows.Forms.MenuItem();
            this.closeMenuItem = new System.Windows.Forms.MenuItem();

            this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
            this.openFileDialog.DefaultExt = "mp3";
            this.openFileDialog.InitialDirectory = Environment.SpecialFolder.MyMusic.ToString();

            browseFolderDialog = new System.Windows.Forms.FolderBrowserDialog();

            this.closeMenuItem.Text = "Close";
            this.closeMenuItem.Click += new System.EventHandler(this.closeMenuItem_Click);

            this.mainMenu.MenuItems.Add(this.fileMenuItem);
            this.fileMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.closeMenuItem });
            this.fileMenuItem.Text = "File";

            this.Menu = this.mainMenu;
        }

        private void browseButton_Click(object sender, EventArgs e)
        {
            // Show the FolderBrowserDialog.
            DialogResult result = openFileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                if (currentFile == openFileDialog.FileName)
                    return;

                OpenFile(openFileDialog.FileName);
            }
        }

        private void OpenFile(string fileName)
        {
            newSongSelected = true;

            currentFile = fileName;
            currentFolder = fileName.Substring(0, fileName.LastIndexOf("\\") + 1);

            List<string> filesInFolder = Directory.GetFiles(currentFolder).ToList();

            List<string> musicFilesInFolder = filesInFolder.Where(x => acceptedFileTypes.Any(a => x.Contains(a))).ToList();

            if (musicFilesInFolder.Count != 0)
            {
                SongsInFolder = getAllSongProperties(musicFilesInFolder);

                addSongsToList(SongsInFolder);

                setCurrentlyPlayingProperties(SongsInFolder.Where(x => x.Path == currentFile).SingleOrDefault());

                setAlbumArt(filesInFolder);
            }
        }

        private void addSongsToList(List<Song> SongsInFolder)
        {
            int count = 0;
            songListPanel.Controls.Clear();
            SongLabels.Clear();

            foreach(var song in SongsInFolder)
            {
                int track = song.Track;

                ToolStripMenuItem playMenuItem = new ToolStripMenuItem("Play", null, delegate(object sender, EventArgs e) { setupSongChange(track); });
                ToolStripMenuItem OpenLocationMenuItem = new ToolStripMenuItem("Open File Location", null,  delegate(object sender, EventArgs e) { openFileLocationClick(sender, e, song.Path); });

                ContextMenuStrip rightClickMenu = new ContextMenuStrip();

                rightClickMenu.Items.AddRange(new ToolStripItem[] {playMenuItem, OpenLocationMenuItem});
               
                Label trackLabel = new Label();
                trackLabel.Text = song.Track.ToString();
                trackLabel.Font = new Font("Microsoft Sans Serif", 14);
                trackLabel.AutoSize = true;
                trackLabel.Height = 30;
                trackLabel.Width = 40;
                trackLabel.Location = new Point(0, 0);
                trackLabel.MouseClick += delegate(object sender, MouseEventArgs e) { songPanel_Click(sender, e, track, rightClickMenu); };
                trackLabel.Cursor = Cursors.Hand;

                Label songLabel = new Label();
                songLabel.Text = song.Title;
                songLabel.Font = new Font("Microsoft Sans Serif", 14);
                songLabel.AutoSize = true;
                songLabel.Width = 300;
                songLabel.Height = 30;
                songLabel.Location = new Point(45, 0);
                songLabel.MouseClick += delegate(object sender, MouseEventArgs e) { songPanel_Click(sender, e, track, rightClickMenu); };
                songLabel.Cursor = Cursors.Hand;

                Panel panel = new Panel();
                panel.Location = new Point(0, 5 + count);
                panel.AutoSize = true;
                panel.Width = 300;
                panel.Height = 30;
                panel.MouseClick += delegate(object sender, MouseEventArgs e){ songPanel_Click(sender, e, track, rightClickMenu); };
                panel.Cursor = Cursors.Hand;
  
                panel.Controls.Add(trackLabel);
                panel.Controls.Add(songLabel);
                songListPanel.Controls.Add(panel);
                SongLabels.Add(songLabel);
                count += 30;
            }
        }

        private void playButton_MouseDown(object sender, MouseEventArgs e)
        {
            playButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\play-downLarge.png");
        }

        private void playButton_MouseUp(object sender, MouseEventArgs e)
        {
            PlaySong();
        }

        private void PlaySong()
        {
            playButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\play-upLarge.png");

            if (String.IsNullOrEmpty(currentFile))
                return;

            if (!MediaPlayer.getIsOpen() || (MediaPlayer.getIsOpen() && newSongSelected))
            {
                newSongSelected = false;

                if (MediaPlayer.getIsOpen())
                {
                    MediaPlayer.Close();
                    timer1.Stop();
                }

                MediaPlayer.Open(currentFile);
                MediaPlayer.MasterVolume = volumeSlider.Value;
                songTimeLabel.Text = "0:00";
                songLengthLabel.Text = convertToTime((int)currentSong.LengthSeconds).ToString();
                positionSlider.Maximum = (int)currentSong.LengthMilliseconds;
                positionSlider.Value = positionSlider.Minimum; // reset the slider
            }

            MediaPlayer.Play(false);
            timer1.Start();
        }

        private void pauseButton_MouseDown(object sender, MouseEventArgs e)
        {
            pauseButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\pause-downLarge.png");
        }

        private void pauseButton_MouseUp(object sender, MouseEventArgs e)
        {
            pauseButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\pause-upLarge.png");

            MediaPlayer.Pause();
            timer1.Stop();
        }

        private void stopButton_MouseDown(object sender, MouseEventArgs e)
        {
            stopButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\stop-downLarge.png");
        }

        private void stopButton_MouseUp(object sender, MouseEventArgs e)
        {
            stopButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\stop-upLarge.png");

            MediaPlayer.Close();
            timer1.Stop();
            positionSlider.Value = positionSlider.Minimum;
            songTimeLabel.Text = "0:00";
        }

        private void previousButton_MouseDown(object sender, MouseEventArgs e)
        {
            previousButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\previous-downLarge.png");
        }

        private void previousButton_MouseUp(object sender, MouseEventArgs e)
        {
            previousButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\previous-upLarge.png");

            int index = SongsInFolder.IndexOf(SongsInFolder.Where(x => x.Path == currentFile).SingleOrDefault());

            int newIndex = index - 1 < 0 ? SongsInFolder.Count - 1 : index - 1;

            changeSong(index, newIndex);
        }

        private void nextButton_MouseDown(object sender, MouseEventArgs e)
        {
            nextButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\next-downLarge.png");
        }

        private void nextButton_MouseUp(object sender, MouseEventArgs e)
        {
            nextButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\next-upLarge.png");

            int index = SongsInFolder.IndexOf(SongsInFolder.Where(x => x.Path == currentFile).SingleOrDefault());

            int newIndex = index + 1 > SongsInFolder.Count - 1 ? 0 : index + 1;

            changeSong(index, newIndex);
        }

        private void positionSliderButton_MouseDown(object sender, MouseEventArgs e)
        {
            positionSliderButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\positionMove-down.png");
        }

        private void positionSliderButton_MouseUp(object sender, MouseEventArgs e)
        {
            positionSliderButton.Image = Image.FromFile(rootDirectory + @"\Images\Large Icons\positionMove-up.png");
        }

        private void setCurrentlyPlayingProperties(Song song)
        {
            currentSong = song;

            titleValue.Text = song.Title;
            artistValue.Text = song.Artist;
            albumValue.Text = song.Album;

            Label label = SongLabels[SongsInFolder.IndexOf(song)];
            label.Font = new Font(label.Font, FontStyle.Bold);      
        }

        private List<Song> getAllSongProperties(List<String> musicFilesInFolder)
        {
            List<Song> listOfSongs = new List<Song>();

            foreach(var musicFile in musicFilesInFolder)
            {
                listOfSongs.Add(new Song(musicFile));
            }

            return listOfSongs.OrderBy(x => x.Track).ToList();
        }

        private void setAlbumArt(List<string> filesInFolder)
        {
            
            string albumArt = filesInFolder.Where(x => x.Contains(".jpg") && x.Contains("Large")).FirstOrDefault();

            if(albumArt == null)
                albumArt = filesInFolder.Where(x => x.Contains(".jpg")).FirstOrDefault();

            if (!String.IsNullOrEmpty(albumArt))
                albumArtImage.Image = Image.FromFile(albumArt);
        }

        

        private void closeMenuItem_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(MediaPlayer.getIsOpen())
                MediaPlayer.Close();
        }

       

        private void songPanel_Click(object sender, MouseEventArgs e, int track, ContextMenuStrip rightClickMenu)
        {
            Control control = (Control)sender;

            MouseButtons button = e.Button;
            if (button == MouseButtons.Left)
            {
                setupSongChange(track);
            }
            else if (button == MouseButtons.Right)
            {
                rightClickMenu.Show(control, new Point(e.X, e.Y));
            }
        }

        private void setupSongChange(int track)
        {
            int index = SongsInFolder.IndexOf(SongsInFolder.Where(x => x.Path == currentFile).SingleOrDefault());

            changeSong(index, track - 1);
        }

        private void changeSong(int oldIndex, int indexOfSong)
        {
            if (MediaPlayer.getIsOpen())
            {
                MediaPlayer.Close();
                timer1.Stop();
            }

            Label label = SongLabels[oldIndex];
            label.Font = new Font(label.Font, FontStyle.Regular);

            Song newSong = SongsInFolder[indexOfSong];

            currentFile = newSong.Path;
            currentSong = newSong;

            setCurrentlyPlayingProperties(currentSong);

            MediaPlayer.Open(currentSong.Path);
            MediaPlayer.MasterVolume = volumeSlider.Value;
            songTimeLabel.Text = "0:00";
            songLengthLabel.Text = convertToTime((int)currentSong.LengthSeconds).ToString();
            positionSlider.Maximum = (int)currentSong.LengthMilliseconds;
            positionSlider.Value = positionSlider.Minimum; // reset the slider
            MediaPlayer.Play(false);
            timer1.Start();
        }

        double oldPosition = 0;

        private void timer1_Tick(object sender, EventArgs e)
        {
            int position = Int32.Parse(MediaPlayer.Position());
            int positionSeconds = (int)position/1000;
            
            if (positionSeconds == 0)
                return;

            double sliderValue = position;


            if (sliderValue < positionSlider.Maximum && oldPosition != position)
            {
                oldPosition = position;

                if (!songPositionIsScrolling)
                {
                    positionSlider.Value = (int)sliderValue;
                }
                songTimeLabel.Text = convertToTime(positionSeconds);
            }
            else
            {
                if (!songPositionIsScrolling)
                {
                    timer1.Stop();
                    positionSlider.Value = positionSlider.Maximum;
                    songTimeLabel.Text = convertToTime((int)currentSong.LengthSeconds).ToString();
                    if (currentSong != SongsInFolder.Last())
                    {
                        changeSong(currentSong.Track - 1, currentSong.Track); // changes to next song (track = index of next song)
                    }
                }
            }
        }

        private string convertToTime(int seconds)
        {
            string positionString = seconds % 60 < 10 ? "0" + seconds % 60 : (seconds % 60).ToString();
            return seconds / 60 + ":" + positionString;
        }

        private void positionSlider_Scroll(object sender, EventArgs e)
        {
            songPositionIsScrolling = true;
        }

        private int songPositionMouseDownPosition = 0;

        private void positionSlider_MouseDown(object sender, MouseEventArgs e)
        {
            songPositionMouseDownPosition = e.X;
        }

        private void positionSlider_MouseUp(object sender, MouseEventArgs e)
        {
            if (songPositionMouseDownPosition == e.X)
            {
                timer1.Stop();
                songPositionIsScrolling = false;
                double percentage = (double)e.X / (double)positionSlider.Width;
                positionSlider.Value = (int)(positionSlider.Maximum * percentage);
                MediaPlayer.Seek(positionSlider.Value);
                songTimeLabel.Text = convertToTime(Int32.Parse(MediaPlayer.Position()) / 1000);
                MediaPlayer.Play(false);
                timer1.Start();
            }
            else if(songPositionIsScrolling)
            {
                timer1.Stop();
                songPositionIsScrolling = false;
                int value = positionSlider.Value;
                MediaPlayer.Seek(value);
                songTimeLabel.Text = convertToTime(Int32.Parse(MediaPlayer.Position()) / 1000);
                MediaPlayer.Play(false);
                timer1.Start();
            }
        }

        private int volumeMouseDownPosition = 0;

        private void volumeSlider_Scroll(object sender, EventArgs e)
        {
            int value = volumeSlider.Value;
            MediaPlayer.MasterVolume = value;
        }

        private void volumeSlider_MouseDown(object sender, MouseEventArgs e)
        {
            volumeMouseDownPosition = e.X;
        }

        private void volumeSlider_MouseUp(object sender, MouseEventArgs e)
        {
            if (volumeMouseDownPosition == e.X)
            {
                double percentage = (double)e.X / (double)volumeSlider.Width;
                volumeSlider.Value = (int)(volumeSlider.Maximum * percentage);
                MediaPlayer.MasterVolume = volumeSlider.Value;
            }
        }

        private void openFileLocationClick(object sender, EventArgs e, string path)
        {
            if (!String.IsNullOrEmpty(path))
                Process.Start("explorer.exe", path.Substring(0,path.LastIndexOf("\\")));       
        }

        public void noLibraryLabelSetText(string text)
        {
            noLibraryLabel.Text = text;
        }

        public void noLibraryPanelShow(bool show)
        {
            if (show) noLibraryPanel.Show();
            else noLibraryPanel.Hide();
        }

        private void libraryBrowseButton_Click(object sender, EventArgs e)
        {
            DialogResult result = browseFolderDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                Library.LibraryPath = browseFolderDialog.SelectedPath;
                iniFile.IniWriteValue("Library", "libraryPath", Library.LibraryPath);
            }

            Library.BuildLibrary();
            DrawAlbums();
        }

        Artist SelectedArtist;
        Dictionary<Artist, List<PictureBox>> ArtistAlbums = new Dictionary<Artist, List<PictureBox>>();
        Dictionary<Artist, Label> ArtistLabels = new Dictionary<Artist, Label>();
        /*
        private void DrawAlbums()
        {
            if (Library.Artists.Count() > 0)
                libraryPanel.Controls.Clear();

            int positionX = 10;
            int row = 0;

            int pictureBoxModY = artistRows == 1 ? 95 : 55;

            Panel rowPanel = new Panel();
            rowPanel.Width = libraryPanel.Width - 70;
            rowPanel.BorderStyle = BorderStyle.FixedSingle;
            rowPanel.Height = 190;
            rowPanel.Location = new Point(35, pictureBoxModY + row * (rowPanel.Height));

            ArtistAlbums.Clear();
            ArtistLabels.Clear();

            for (int x = 0; x < artistsPerRow * artistRows && (libraryPage * artistsPerRow * artistRows) + x < Library.Artists.Count(); x++)
            {
                Artist artist = Library.Artists[(libraryPage * artistsPerRow * artistRows) + x];
                List<PictureBox> albums = new List<PictureBox>();

                int modifierX = 130;
                int modifierY = 106;
                int intitialY = 50;

                if (x % artistsPerRow == 0 && x > 0)
                {
                    rowPanel = new Panel();
                    rowPanel.Width = libraryPanel.Width - 70;
                    rowPanel.BorderStyle = BorderStyle.FixedSingle;
                    rowPanel.Height = 130;
                    rowPanel.Location = new Point(35, pictureBoxModY + row * (rowPanel.Height));
                    positionX = 10;
                    row++;
                }

                for (int y = 0; y < artist.Albums.Count(); y++)
                {
                    PictureBox pictureBox = new PictureBox();

                    pictureBox.Width = modifierX;
                    pictureBox.Height = modifierY;
                    pictureBox.BorderStyle = BorderStyle.FixedSingle;
                    pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
                    pictureBox.Image = Image.FromFile(artist.Albums[y].AlbumArtPath);
                    pictureBox.SendToBack();
                    pictureBox.Location = new Point((positionX), intitialY - y * 10);
                    
                    // Prevents adding too many albums
                    if (y < 5 && (artistRows == 1 || y < 1))
                        rowPanel.Controls.Add(pictureBox);

                    albums.Add(pictureBox);
                }

                PictureBox album = albums.First();

                album.Tag = artist;
                album.MouseEnter += new EventHandler(album_MouseEnter);
                album.MouseLeave += new EventHandler(album_MouseLeave);

                album.Click += new EventHandler(album_Click);

                // Artist Label
                Label artistLabel = new Label();
                artistLabel.AutoSize = true;
                artistLabel.Text = artist.ArtistName;  
                artistLabel.Font = new Font("Microsoft Sans Serif", (float)(10));
                

                rowPanel.Controls.Add(artistLabel);

                artistLabel.Location = new Point((positionX + modifierX / 2 - artistLabel.Width / 2), intitialY + modifierY + 10);

                libraryPanel.Controls.Add(rowPanel);

                ArtistLabels.Add(artist, artistLabel);
                ArtistAlbums.Add(artist, albums);

                positionX += modifierX + 20;
            }

            if (Library.Artists.Count() > 0)
            {
                Button left = new Button();
                left.Width = 20;
                left.Height = 90;
                left.AutoSize = true;
                left.Text = "<";
                left.Location = new Point(0, libraryPanel.Height/2 - left.Height/2);
                left.Click += new EventHandler(OnLeftClick);

                Button right = new Button();
                right.Width = 20;
                right.Height = 90;
                right.AutoSize = true;
                right.Text = ">";
                right.Location = new Point(libraryPanel.Width - right.Width-13, libraryPanel.Height/2 - right.Height/2);
                right.Click += new EventHandler(OnRightClick);

                Button listButton = new Button();
                listButton.Width = 80;
                listButton.Height = 30;
                listButton.Text = "List";
                listButton.Location = new Point(0, 5);
                listButton.Click += new EventHandler(DrawArtistListView);

                Button tileButton = new Button();
                tileButton.Width = 80;
                tileButton.Height = 30;
                tileButton.Text = "Tile";
                tileButton.Location = new Point(listButton.Width + 5, 5);
                tileButton.Click += new EventHandler(DrawArtistTileView);

                libraryPanel.Controls.Add(listButton);
                libraryPanel.Controls.Add(tileButton);
                libraryPanel.Controls.Add(left);
                libraryPanel.Controls.Add(right);
            }
        }
        */
        private void DrawAlbums()
        {
            if (Library.Artists.Count() > 0)
                libraryPanel.Controls.Clear();

            ArtistAlbums.Clear();
            ArtistLabels.Clear();

            int row = 0;
            int positionX = 10;
            int intitialY = 50;
            int modifierX = 130;
            int modifierY = 106;
            int rowPanelHeight = 190;
            int rowPanelY = libraryPanel.Height / 2 - rowPanelHeight / 2;

            if (artistRows > 1)
            {
                intitialY = 10;
                rowPanelY = 40;
                rowPanelHeight = 150;
            }

            Panel rowPanel = new Panel();
            rowPanel.Width = libraryPanel.Width - 70;
            rowPanel.Height = rowPanelHeight;
            rowPanel.Location = new Point(35, rowPanelY);

            for (int x = 0; x < artistsPerRow * artistRows && (libraryPage * artistsPerRow * artistRows) + x < Library.Artists.Count(); x++)
            {
                Artist artist = Library.Artists[(libraryPage * artistsPerRow * artistRows) + x];
                List<PictureBox> albums = new List<PictureBox>();

                if (x % artistsPerRow == 0 && x > 0)
                {
                    row++;
                    positionX = 10;
                    rowPanel = new Panel();
                    rowPanel.Width = libraryPanel.Width - 70;
                    rowPanel.Height = rowPanelHeight;
                    rowPanel.Location = new Point(35, rowPanelY + row *(rowPanel.Height));
                }

                for (int y = 0; y < artist.Albums.Count(); y++)
                {
                    PictureBox pictureBox = new PictureBox();

                    pictureBox.Width = modifierX;
                    pictureBox.Height = modifierY;
                    pictureBox.BorderStyle = BorderStyle.FixedSingle;
                    pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
                    pictureBox.Image = Image.FromFile(artist.Albums[y].AlbumArtPath);
                    pictureBox.SendToBack();
                    pictureBox.Location = new Point((positionX), intitialY - y * 10);

                    // Prevents adding too many albums
                    if (y < 5 && (artistRows == 1 || y < 1))
                        rowPanel.Controls.Add(pictureBox);

                    albums.Add(pictureBox);
                }

                PictureBox album = albums.First();

                album.Tag = artist;
                album.MouseEnter += new EventHandler(album_MouseEnter);
                album.MouseLeave += new EventHandler(album_MouseLeave);

                album.Click += new EventHandler(album_Click);

                // Artist Label
                Label artistLabel = new Label();
                artistLabel.AutoSize = true;
                artistLabel.Text = artist.ArtistName;
                artistLabel.Font = new Font("Microsoft Sans Serif", (float)(10));


                rowPanel.Controls.Add(artistLabel);

                artistLabel.Location = new Point((positionX + modifierX / 2 - artistLabel.Width / 2), intitialY + modifierY + 10);

                libraryPanel.Controls.Add(rowPanel);

                ArtistLabels.Add(artist, artistLabel);
                ArtistAlbums.Add(artist, albums);

                positionX += modifierX + 20;
            }

            if (Library.Artists.Count() > 0)
            {
                Button left = new Button();
                left.Width = 20;
                left.Height = 90;
                left.AutoSize = true;
                left.Text = "<";
                left.Location = new Point(0, libraryPanel.Height / 2 - left.Height / 2);
                left.Click += new EventHandler(OnLeftClick);

                Button right = new Button();
                right.Width = 20;
                right.Height = 90;
                right.AutoSize = true;
                right.Text = ">";
                right.Location = new Point(libraryPanel.Width - right.Width - 13, libraryPanel.Height / 2 - right.Height / 2);
                right.Click += new EventHandler(OnRightClick);

                Button listButton = new Button();
                listButton.Width = 80;
                listButton.Height = 30;
                listButton.Text = "List";
                listButton.Location = new Point(0, 5);
                listButton.Click += new EventHandler(DrawArtistListView);

                Button tileButton = new Button();
                tileButton.Width = 80;
                tileButton.Height = 30;
                tileButton.Text = "Tile";
                tileButton.Location = new Point(listButton.Width + 5, 5);
                tileButton.Click += new EventHandler(DrawArtistTileView);

                libraryPanel.Controls.Add(listButton);
                libraryPanel.Controls.Add(tileButton);
                libraryPanel.Controls.Add(left);
                libraryPanel.Controls.Add(right);
            }
        }

        private void DrawArtistListView(object sender, EventArgs e)
        {
            artistRows = 1;
            DrawAlbums();
        }

        private void DrawArtistTileView(object sender, EventArgs e)
        {
            artistRows = 3;

            while (libraryPage * artistsPerRow * artistRows > Library.Artists.Count())
            {
                libraryPage--;
            }

            DrawAlbums();
        }

        private void OnLeftClick(object sender, EventArgs e)
        {
            if (libraryPage != 0)
            {
                libraryPage--;
                DrawAlbums();
            }
        }

        private void OnRightClick(object sender, EventArgs e)
        {
            if ((libraryPage + 1) * artistsPerRow * artistRows < Library.Artists.Count())
            {
                libraryPage++;
                DrawAlbums();
            }
        }

        private void album_MouseEnter(object sender, EventArgs e)
        {
            SelectedArtist = (Artist)((PictureBox)sender).Tag;
            UpdateArtistAlbumSelected(SelectedArtist);
        }

        private void album_MouseLeave(object sender, EventArgs e)
        {
            SelectedArtist = null;
            UpdateArtistAlbumSelected((Artist)((PictureBox)sender).Tag);
        }

        private void album_Click(object sender, EventArgs e)
        {
            SelectedArtist = (Artist)((PictureBox)sender).Tag;
            DrawArtistView();
        }

        private void UpdateArtistAlbumSelected(Artist artist)
        {
            int positionY = 1;
            int modifierX = 0;
            int modifierY = 0;

            foreach (PictureBox pictureBox in ArtistAlbums[artist])
            {
                if (artist == SelectedArtist)
                {
                    modifierX = 150;
                    modifierY = 126;

                    pictureBox.Size = new Size(modifierX, modifierY);
                    pictureBox.Location = new Point(pictureBox.Location.X - 10, pictureBox.Location.Y - 10);
                    pictureBox.SendToBack();
                    positionY++;
                }
                else
                {
                    modifierX = 130;
                    modifierY = 106;

                    pictureBox.Size = new Size(modifierX, modifierY);
                    pictureBox.Location = new Point(pictureBox.Location.X + 10, pictureBox.Location.Y + 10);
                    pictureBox.SendToBack();
                    positionY++;
                }
            }
        }

        private void DrawArtistView()
        {
            libraryPanel.Controls.Clear();
            ArtistAlbums[SelectedArtist].First().MouseEnter -= new EventHandler(album_MouseEnter);
            ArtistAlbums[SelectedArtist].First().MouseLeave -= new EventHandler(album_MouseLeave);
            ArtistAlbums[SelectedArtist].First().Click -= new EventHandler(album_Click);

            int libraryPanelWidth = libraryPanel.Width - 17;

            int positionX = 10;
            int positionY = 0;

            Button backButton = new Button();
            backButton.Height = 20;
            backButton.AutoSize = true;
            backButton.Text = "Back to Library";
            backButton.Location = new Point(positionX, positionY);
            backButton.Click += delegate(object sender, EventArgs e) { SelectedArtist = null; DrawAlbums(); };
            libraryPanel.Controls.Add(backButton);

            Panel scrollPanel = new Panel();

            CustomScrollBar scrollUp = new CustomScrollBar("ScrollBar", scrollPanel, ScrollType.Up, libraryPanelWidth - (2 * positionX), 1, false);
            scrollUp.Location = new Point(positionX, backButton.Height + 5);
            libraryPanel.Controls.Add(scrollUp);

            scrollPanel.AutoScroll = true;
            scrollPanel.BorderStyle = BorderStyle.FixedSingle;
            scrollPanel.Size = new System.Drawing.Size(libraryPanelWidth - (2 * positionX), libraryPanel.Height - (backButton.Height + scrollUp.Height*2 + 11));
            scrollPanel.Location = new Point(positionX, backButton.Height + scrollUp.Height + 8);

            CustomScrollBar scrollDown = new CustomScrollBar("ScrollBar", scrollPanel, ScrollType.Down, libraryPanelWidth - (2 * positionX), 1, false);
            scrollDown.Location = new Point(positionX, scrollPanel.Location.Y + scrollPanel.Height+ 3);
            libraryPanel.Controls.Add(scrollDown);

            List<Album> albums = SelectedArtist.Albums;

            positionX = 0;
            positionY = 0;
            int index = 0;

            foreach (PictureBox pictureBox in ArtistAlbums[SelectedArtist])
            {
                Panel albumPanel = new Panel();
                albumPanel.BorderStyle = BorderStyle.FixedSingle;
                albumPanel.AutoSize = true;
                albumPanel.Width = libraryPanelWidth - (2 * positionX);
                albumPanel.MaximumSize = new System.Drawing.Size(scrollPanel.Width - 20, 1000);

                int width = 150;
                int height = 126;

                pictureBox.Size = new Size(width, height);
                pictureBox.Location = new Point(5, 5);
                albumPanel.Controls.Add(pictureBox);

                SpecialLabel artistNameLabel = new SpecialLabel();
                artistNameLabel.AutoSize = true;
                //artistNameLabel.MaximumSize = new System.Drawing.Size(255, 40);
                artistNameLabel.Text = "Artist: " + SelectedArtist.ArtistName;
                artistNameLabel.Font = new Font("Microsoft Sans Serif", (float)(13));
                artistNameLabel.Location = new Point(pictureBox.Location.X, pictureBox.Location.Y + pictureBox.Height + 10);
                albumPanel.Controls.Add(artistNameLabel);

                SpecialLabel albumNameLabel = new SpecialLabel();
                albumNameLabel.AutoSize = true;
                //albumNameLabel.MaximumSize = new System.Drawing.Size(255, 40);
                albumNameLabel.Text = "Album: " + SelectedArtist.Albums[index].Title;
                albumNameLabel.Font = new Font("Microsoft Sans Serif", (float)(13));
                albumNameLabel.Location = new Point(artistNameLabel.Location.X, artistNameLabel.Location.Y + artistNameLabel.Height + 5);
                albumPanel.Controls.Add(albumNameLabel);

                SpecialLabel albumYearLabel = new SpecialLabel();
                albumYearLabel.AutoSize = true;
                //albumYearLabel.MaximumSize = new System.Drawing.Size(255, 40);
                albumYearLabel.Text = "Year: " + SelectedArtist.Albums[index].Year;
                albumYearLabel.Font = new Font("Microsoft Sans Serif", (float)(13));
                albumYearLabel.Location = new Point(albumNameLabel.Location.X, albumNameLabel.Location.Y + albumNameLabel.Height + 5);
                albumPanel.Controls.Add(albumYearLabel);

                int count = 0;

                foreach (Song song in albums[index].Songs)
                {
                    int songX = 255;
                    string path = song.Path;

                    ToolStripMenuItem playMenuItem = new ToolStripMenuItem("Play", null, delegate(object sender, EventArgs e) { OpenFile(path); PlaySong(); });
                    ToolStripMenuItem OpenLocationMenuItem = new ToolStripMenuItem("Open File Location", null, delegate(object sender, EventArgs e) { openFileLocationClick(sender, e, path); });

                    ContextMenuStrip rightClickMenu = new ContextMenuStrip();

                    rightClickMenu.Items.AddRange(new ToolStripItem[] {playMenuItem, OpenLocationMenuItem});
               
                    Label trackLabel = new Label();
                    trackLabel.Text = song.Track.ToString();
                    trackLabel.Font = new Font("Microsoft Sans Serif", (float)(12));
                    trackLabel.AutoSize = true;
                    trackLabel.Height = 25;
                    trackLabel.Width = 40;
                    trackLabel.Location = new Point(0, 0);
                    trackLabel.MouseClick += delegate(object sender, MouseEventArgs e) { librarySongPanel_Click(sender, e, path, rightClickMenu); };
                    trackLabel.Cursor = Cursors.Hand;

                    Label songLabel = new Label();
                    songLabel.Text = song.Title;
                    songLabel.Font = new Font("Microsoft Sans Serif", (float)(12));
                    songLabel.AutoSize = true;
                    songLabel.Height = 25;
                    songLabel.MaximumSize = new System.Drawing.Size(libraryPanelWidth - ((2 * positionX) + songX + trackLabel.Width), 30);
                    songLabel.Location = new Point(45, 0);
                    songLabel.MouseClick += delegate(object sender, MouseEventArgs e) { librarySongPanel_Click(sender, e, path, rightClickMenu); };
                    songLabel.Cursor = Cursors.Hand;

                    Panel songPanel = new Panel();
                    songPanel.Location = new Point(songX + 30 + 10, 25 * count + 5);
                    songPanel.AutoSize = true;
                    songPanel.Width = 300;
                    songPanel.Height = 25;
                    songPanel.MouseClick += delegate(object sender, MouseEventArgs e) { librarySongPanel_Click(sender, e, path, rightClickMenu); };
                    songPanel.Cursor = Cursors.Hand;

                    songPanel.Controls.Add(trackLabel);
                    songPanel.Controls.Add(songLabel);
                    albumPanel.Controls.Add(songPanel);
                    count++;
                }

                albumPanel.Location = new Point(positionX, positionY);
                scrollPanel.Controls.Add(albumPanel);

                positionY += albumPanel.Height + 10;
                index++;
            }

            libraryPanel.Controls.Add(scrollPanel);
        }

        private void librarySongPanel_Click(object sender, MouseEventArgs e, string path, ContextMenuStrip rightClickMenu)
        {
            Control control = (Control)sender;

            MouseButtons button = e.Button;
            if (button == MouseButtons.Left)
            {
                OpenFile(path);
                PlaySong();
            }
            else if (button == MouseButtons.Right)
            {
                rightClickMenu.Show(control, new Point(e.X, e.Y));
            }
        }
    }
}
